package com.mall.user.services;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mall.user.IUserLoginService;
import com.mall.user.constants.SysRetCodeConstants;
import com.mall.user.converter.MemberConverter;
import com.mall.user.dal.entitys.Member;
import com.mall.user.dal.entitys.UserVerify;
import com.mall.user.dal.persistence.MemberMapper;
import com.mall.user.dal.persistence.UserVerifyMapper;
import com.mall.user.dto.*;
import com.mall.user.mq.producer.SendMailProducer;
import com.mall.user.utils.ExceptionProcessorUtils;
import com.mall.user.utils.JwtTokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
@Service
@Transactional
public class UserLoginServiceImpl implements IUserLoginService {
    @Autowired
    MemberMapper memberMapper;

    @Autowired
    UserVerifyMapper userVerifyMapper;

    @Autowired
    MemberConverter memberConverter;

    @Autowired
    SendMailProducer sendMail;


    /**
     * tokenhandler里面的解析
     * @param request 解析请求,携带token
     * @return 携带用户信息响应
     */
    @Override
    public CheckAuthResponse validToken(CheckAuthRequest request) {
        CheckAuthResponse checkAuthResponse = new CheckAuthResponse();

        String token = request.getToken();
        String memberStr = JwtTokenUtils.builder().token(token).build().freeJwt();
        checkAuthResponse.setUserinfo(memberStr);
        try {
            JSONObject jsonObject = JSON.parseObject(memberStr);
        }catch (Exception e){
            checkAuthResponse.setCode(SysRetCodeConstants.TOKEN_VALID_FAILED.getCode());
            checkAuthResponse.setMsg(SysRetCodeConstants.TOKEN_VALID_FAILED.getMessage());
            return checkAuthResponse;
        }
        checkAuthResponse.setCode(SysRetCodeConstants.SUCCESS.getCode());
        checkAuthResponse.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
        return checkAuthResponse;
    }

    @Override
    public UserLoginResponse login(UserLoginRequest request) {
        UserLoginResponse response = new UserLoginResponse();
        try {
            //检验参数
            request.requestCheck();
        } catch (Exception e) {
            log.error("MemberServiceImpl.login Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        //数据库查询用户
        Example example = new Example(Member.class);
        //md5加密算法,加密密码
        String encodePwd = DigestUtils.md5DigestAsHex(request.getPassword().getBytes());
        example.createCriteria().andEqualTo("username", request.getUserName()).andEqualTo("password", encodePwd);
        List<Member> members = memberMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(members)) {
            //获取token,将对象member对象存入token中
            Member member = members.get(0);
            //判断用户是否激活
            if(!"Y".equals(member.getIsVerified())){
                response.setCode(SysRetCodeConstants.USER_ISVERFIED_ERROR.getCode());
                response.setMsg(SysRetCodeConstants.USER_ISVERFIED_ERROR.getMessage());
                return response;
            }
            Map<String, Object> map = new HashMap<>();
            map.put("uid", member.getId());
            map.put("username", member.getUsername());

//            ObjectMapper objectMapper = new ObjectMapper();
//            String msg = null;
//            try {
//                msg = objectMapper.writeValueAsString(map);
//            } catch (JsonProcessingException e) {
//                e.printStackTrace();
//            }
            String token = JwtTokenUtils.builder().msg(JSON.toJSONString(map)).build().creatJwtToken();
//            String token = JwtTokenUtils.builder().msg(msg).build().creatJwtToken();
            response = memberConverter.member2LoginRes(members.get(0), token);
            response.setCode(SysRetCodeConstants.SUCCESS.getCode());
            response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
        }else {
            response.setCode(SysRetCodeConstants.USERORPASSWORD_ERRROR.getCode());
            response.setMsg(SysRetCodeConstants.USERORPASSWORD_ERRROR.getMessage());
        }
        return response;
    }

    @Override
    public UserRegisterResponse register(UserRegisterRequest request) {
        UserRegisterResponse response = new UserRegisterResponse();
        try {
            request.requestCheck();
        } catch (Exception e) {
            log.error("MemberServiceImpl.login Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
            return response;
        }
        //判断注册的用户是否已经存在
        String userName = request.getUserName();
        Example example = new Example(Member.class);
        example.createCriteria().andEqualTo("username", userName);
        List<Member> members = memberMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(members)) {
            response.setCode(SysRetCodeConstants.USERNAME_ALREADY_EXISTS.getCode());
            response.setMsg(SysRetCodeConstants.USERNAME_ALREADY_EXISTS.getMessage());
            return response;
        }
        //插入用户数据
        Member member = new Member();
        member.setUsername(userName);
        //加密密码
        String encodeUserPwd = DigestUtils.md5DigestAsHex(request.getUserPwd().getBytes());
        member.setPassword(encodeUserPwd);
        member.setEmail(request.getEmail());
        Date now = new Date();
        member.setCreated(now);
        member.setUpdated(now);
        int insertRow = memberMapper.insertSelective(member);
        if(insertRow == 0) {
            response.setCode(SysRetCodeConstants.USER_REGISTER_FAILED.getCode());
            response.setMsg(SysRetCodeConstants.USER_REGISTER_FAILED.getMessage());
            return response;
        }
        //插入用户验证数据
        UserVerify userVerify = new UserVerify();
        userVerify.setUsername(userName);
        userVerify.setRegisterDate(now);
        //生成用户唯一标识,用户名+密码+当前时间,md5加密
        String uuid = DigestUtils.md5DigestAsHex((encodeUserPwd + userName + System.currentTimeMillis()).getBytes());
        userVerify.setUuid(uuid);
        userVerify.setIsExpire("N");
        userVerify.setIsVerify("N");
        int insert = userVerifyMapper.insertSelective(userVerify);
        if (insert == 0) {
            response.setCode(SysRetCodeConstants.USER_REGISTER_VERIFY_FAILED.getCode());
            response.setMsg(SysRetCodeConstants.USER_REGISTER_VERIFY_FAILED.getMessage());
            return response;
        }
        //往消息队列发送激活邮件
        sendMail.sendMail(uuid,request);

        log.info("用户注册成功,注册参数request{}:",JSON.toJSONString(request));
        response.setCode(SysRetCodeConstants.SUCCESS.getCode());
        response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
        return response;
    }

    @Override
    public UserVerifyResponse verify(UserVerifyRequest request) {
        UserVerifyResponse response = new UserVerifyResponse();
        String uuid = request.getUuid();
        String userName = request.getUserName();
        //参数验证
        try {
            request.requestCheck();
        }catch (Exception e){
            log.error("MemberServiceImpl.login Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
            return response;
        }
        //修改用户激活表
        Example example = new Example(UserVerify.class);
        example.createCriteria().andEqualTo("uuid",uuid);
        UserVerify userVerify = new UserVerify();
        userVerify.setIsVerify("Y");
        int updateRow = userVerifyMapper.updateByExampleSelective(userVerify, example);
        if(updateRow == 0) {
            response.setCode(SysRetCodeConstants.USER_REGISTER_VERIFY_FAILED.getCode());
            response.setMsg(SysRetCodeConstants.USER_REGISTER_VERIFY_FAILED.getMessage());
            return response;
        }
        //修改用户表
        Example example1 = new Example(Member.class);
        example1.createCriteria().andEqualTo("username",userName);
        Member member = new Member();
        member.setIsVerified("Y");
        member.setUpdated(new Date());
        int update = memberMapper.updateByExampleSelective(member, example1);
        if(update == 0){
            response.setCode(SysRetCodeConstants.USER_INFOR_UPDATE_FAIL.getCode());
            response.setMsg(SysRetCodeConstants.USER_INFOR_UPDATE_FAIL.getMessage());
            return response;
        }
        //激活成功
        log.info("用户激活成功,激活参数request:{}",JSON.toJSONString(request));
        response.setCode(SysRetCodeConstants.SUCCESS.getCode());
        response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
        return response;
    }
}
